<?php

/*
  Author:    Alfredo 'IceCoder' Mungo <chimeranet89@gmail.com>
  License:   LGPL
  Copyright: 2013
*/

class HTMLFormHelper {
  
  private $form_attrs;
  private $elements;

  /*
    Initializes a new instance of the HTMLFormHelper class.

    Arguments:
      string $action, $method: The HTML form attribute values
      array[string => string]: other attributes in the form attr-name => attr-value
   */
  function __construct($action,
		       $method = 'GET',
		       $attributes = null) {

    $this->form_attrs = array('action' => $action,
			      'method' => $method,
			      'attrs' => $attributes);

    $this->elements = [];
  }

  /*
    Append an input element to the form.
    
    Arguments:
      string $type..$value: the HTML input attribute values
      string $label: label description (null for no label)
      boolean $labelBefore: true if the label text must be inserted before the element
      array[string => string]: other attributes in the form attr-name => attr-value

    Notes:
      You can append an element of $type='custom' and $name='tag-name'. It will be
      appended as a <$name $attributes> element. You can specify a $value for the
      element. In this case it will be appended as <$name $attributes>$value</$name>.
  */
  public function append($type,
			 $value = null,
			 $name = null,
			 $label = null,
			 $labelBefore = true,
			 $attributes = null) {

    $elm = array('type' => $type,
		 'value' => $value,
		 'name' => $name,
		 'label' => $label,
		 'labelBefore' => $labelBefore,
		 'attrs' => $attributes);

    $this->elements[] = $elm;
  }

  /*
    Generate the HTML output.
        
    Arguments:
      bool $echo: if true, the HTML is directly sent to stdout and returned by the method; if false, the HTML output is only returned by the method

    Returns:
      The HTML code for the form object.
  */
  public function getHTML($echo = false) {
    $html = '<form ' . ($this->form_attrs['action']? 'action="' . $this->form_attrs['action'] . '" ': '') .
      ($this->form_attrs['method']? 'method="' . $this->form_attrs['method'] . '" ': '') .
      $this->attrsHTML($this->form_attrs['attrs']) . '>';

    foreach($this->elements as $elm)
      $html .= $this->elementHTML($elm);

    $html .= '</form>';

    if($echo)
      echo $html;

    return $html;
  }

  /*
    Returns the HTML representation (e.g.: attr1="value1" attr2="value2" ...) of the provided attribute array.

    Arguments:
      array[string => string] attrs: the attributes to translate to HTML
   */
  private function attrsHTML($attrs) {
    $res = '';

    if($attrs !== null)
      foreach($attrs as $name => $value)
	$res .= $name . "=\"$value\" ";

    return $res;
  }


  /*
    Returns the HTML representation of the provided element array.

    Arguments:
     array[string => string] elm: the element to translate to HTML
   */
  private function elementHTML($elm) {
    if($elm['label'] !== null) {
      $res = '<label>' . ($elm['labelBefore']? $elm['label']: '');
      $labeled = true;
    }
    else {
      $res = '';
      $labeled = false;
    }

    if($elm['type'] === 'custom')
      $res .= '<' . $elm['name'] . ' ' . $this->attrsHTML($elm['attrs']) . '>' .
	($elm['value'] !== null? $elm['value'] . '</' . $elm['name'] . '>': '');
    else
      $res .= '<input ' . ($elm['type']? 'type="' . $elm['type'] . '" ': '') .
	($elm['name']? 'name="' . $elm['name'] . '" ': '') . 
	($elm['value']? 'value="' . $elm['value'] . '" ': '') .
	$this->attrsHTML($elm['attrs']) .
	'>';

    if($labeled)
      $res .= ((!$elm['labelBefore'])? ' ' . $elm['label']: '') . '</label>';

    return $res;
  }
}

?>